﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

// <copyright file="SMOperator" company="42ENG">
// Copyright (c) 2014 All Rights Reserved
// <author>Dennis Johnston</author>
// </copyright>
namespace SMOperator
{
    class CatalogContext
    {
        public XDocument Configuration
        { get; set; }

        /// <summary>
        /// Default constructor
        /// </summary>
        public CatalogContext()
        {
            var v = System.Reflection.Assembly.GetExecutingAssembly();
            string appSettings = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules().First().FullyQualifiedName), v.ManifestModule.Name + ".config");
            Configuration = GetXDocumentFromPath(appSettings);
        }
        public bool IsConfigExist
        {
            get
            {
                var v = System.Reflection.Assembly.GetExecutingAssembly();
                string appSettings = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules().First().FullyQualifiedName), v.ManifestModule.Name + ".config");
                return File.Exists(appSettings);
            }
        }
        /// <summary>
        /// Load a connectionstring by name
        /// </summary>
        /// <param name="connectionName"></param>
        /// <returns></returns>
        public string GetConnectionString(string connectionName)
        {
            var connectionstrings = from connectstring
                                    in Configuration.Descendants("connectionStrings")
                                    select connectstring;
            foreach (var cns in connectionstrings)
            {
                foreach (XElement element in cns.Descendants())
                {
                    if (element.Attribute("name").Value == connectionName)
                        return element.Attribute("connectionString").Value;
                }
            }

            return string.Empty;
        }
        /// <summary>
        /// Get a connectionstring by name
        /// </summary>
        /// <param name="connectionName"></param>
        /// <returns></returns>
        public List<string> GetConnectionNames(string connectionName)
        {
            var connectionstrings = from connectstring
                                    in Configuration.Descendants("connectionStrings")
                                    select connectstring;
            List<string> connection = new List<string>();

            foreach (var cns in connectionstrings)
            {
                foreach (XElement element in cns.Descendants())
                {
                    connection.Add(element.Attribute("name").Value);
                }
            }
            return connection;
        }
        /// <summary>
        /// Retrieve an XDocument directly from the filesystem
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static XDocument GetXDocumentFromPath(string path)
        {
            if (!File.Exists(path))
                return new XDocument();

            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            return GetXDocument(doc);
        }
        /// <summary>
        /// Return XDocument (SQL) from an XmlDocument
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public static XDocument GetXDocument(XmlDocument document)
        {
            XDocument xDoc = new XDocument();
            using (XmlWriter xmlWriter = xDoc.CreateWriter())
                document.WriteTo(xmlWriter);
            XmlDeclaration decl = document.ChildNodes.OfType<XmlDeclaration>().FirstOrDefault();
            if (decl != null)
                xDoc.Declaration = new XDeclaration(decl.Version, decl.Encoding, decl.Standalone);
            return xDoc;
        }
        /// <summary>
        /// Remove illegal XML characters from a string.
        /// </summary>
        public static string SanitizeXmlString(string xml)
        {
            if (xml == null)
            {
                throw new ArgumentNullException("xml");
            }

            StringBuilder buffer = new StringBuilder(xml.Length);

            foreach (char c in xml)
            {
                if (IsLegalXmlChar(c))
                {
                    buffer.Append(c);
                }
            }

            return buffer.ToString();
        }

        /// <summary>
        /// Whether a given character is allowed by XML 1.0.
        /// </summary>
        public static bool IsLegalXmlChar(int character)
        {
            return
            (
                 character == 0x9 /* == '\t' == 9   */          ||
                 character == 0xA /* == '\n' == 10  */          ||
                 character == 0xD /* == '\r' == 13  */          ||
                (character >= 0x20 && character <= 0xD7FF) ||
                (character >= 0xE000 && character <= 0xFFFD) ||
                (character >= 0x10000 && character <= 0x10FFFF)
            );
        }

    }
}
